import { Component, Input, OnInit, ViewChild } from '@angular/core';
import { FormBuilder, FormControl, FormGroup, Validators } from "@angular/forms";
import { NzMessageService } from "ng-zorro-antd";
import { Environment } from 'environments/environment';
import { FcsService } from "../../service/fcs.service";
import { Function, EnvVariable } from "../class/instance";

@Component({
  selector: 'app-fcs-config',
  templateUrl: './fcs-config.component.html',
  styleUrls: ['./fcs-config.component.less']
})
export class FcsConfigComponent implements OnInit {
  @ViewChild('functionFormComponent', { static: true }) functionFormComponent;
  @Input() fcsInstance: Function;
  @Input() regionCode: string = 'cn-north-3';
  functionForm: FormGroup;
  runtimeList = [
    { key: 'python2.7', value: 'Python 2.7', code: false },
    { key: 'python3.6', value: 'Python 3.6', code: false },
    { key: 'nodejs10.22', value: 'Nodejs 10.22', code: false },
    { key: 'nodejs12.18', value: 'Nodejs 12.18', code: false },
    { key: 'golang1', value: 'Golang 1', code: false },
    { key: 'java8', value: 'Java 8', code: false },
    { key: 'custom-container', value: '自定义镜像', code: false },
  ];
  RuntimeCustomContainer = "custom-container"
  errorMsg = '';
  isShowSingle: boolean = true;
  isVirtualAccess: boolean = false;
  isLoadingVPC: boolean = false;
  vpcError: boolean = false;
  subnetError: boolean = false;
  vpcId: string;
  vpcList = [];
  subnetId: string;
  subnetList = [];
  firstInit: boolean = true;
  envVariableData: String[] = []; //配置之前的
  envVariables: String[] = []; //配置之后的
  envValid: boolean = true;
  needValid: boolean = false;
  isInternetAccess: boolean = false; //是否开启公网访问权限

  cirImageList = [];
  isInitialize = false;

  constructor(private fb: FormBuilder,
    private fcsService: FcsService,
    private msgService: NzMessageService) {

  }

  ngOnInit() {
    this.initForm();
    this.getVPCList();
  }

  initForm() {
    let isInitialize = false;
    if (this.fcsInstance && this.fcsInstance.initializeHandler && this.fcsInstance.initializeTimeout) {
      isInitialize = true;
    }
    this.isInitialize = isInitialize;

    let containerImage = null,
      containerCommand = "",
      containerArgs = "",
      containerPort = "8080";
    if (this.fcsInstance && this.fcsInstance.runtime == this.RuntimeCustomContainer) {
      containerImage = this.fcsInstance.containerImage;
      containerCommand = this.fcsInstance.containerCommand;
      containerArgs = this.fcsInstance.containerArgs;
      containerPort = this.fcsInstance.containerPort;
    }

    this.functionForm = this.fb.group({
      functionName: [(this.fcsInstance && this.fcsInstance.functionName) || '', [Validators.required, this.nameValidator]],
      groupName: [(this.fcsInstance && this.fcsInstance.groupDisplayName) || '无权限查看应用名称', []],
      description: [(this.fcsInstance && this.fcsInstance.description) || '', [Validators.maxLength(1000), this.descriptionValid]],
      runtime: [(this.fcsInstance && this.fcsInstance.runtime) || '', [Validators.required]],
      handler: [(this.fcsInstance && this.fcsInstance.handler) || '', [Validators.required]],
      memorySize: [(this.fcsInstance && this.fcsInstance.memorySize) || 128, [Validators.required]],
      timeout: [(this.fcsInstance && this.fcsInstance.timeout) || 3, [Validators.required]],
      concurrency: [(this.fcsInstance && this.fcsInstance.concurrency) || 1, [Validators.required]],
      reserveNumber: [(this.fcsInstance && this.fcsInstance.reserveNumber) || 0, [Validators.required]],
      internetAccess: [this.fcsInstance && (this.fcsInstance.enablePublic === 1 ? true : false), [Validators.required]],
      virtualAccess: [this.fcsInstance.enableVpc, [Validators.required]],
      vpc: [(this.fcsInstance.vpcInfo ? this.fcsInstance.vpcInfo['vpcId'] : undefined), [Validators.required]],
      subnet: [(this.fcsInstance.vpcInfo ? this.fcsInstance.vpcInfo['subnetId'] : undefined), [Validators.required]],

      containerImage: [containerImage, [this.containerValidator]],
      containerCommand: [containerCommand, [this.commandValidator]],
      containerArgs: [containerArgs, [this.commandValidator]],
      containerPort: [containerPort, [Validators.pattern("[0-9]*"),
      Validators.pattern("^((?!^(8012|8013|8022|9090|9091|9092)$).)*$"),
      Validators.min(1), Validators.max(65535)]],

      isInitialize: [isInitialize],
      initializeHandler: [(this.fcsInstance && this.fcsInstance.initializeHandler) || "", [this.initValidator]],
      initializeTimeout: [(this.fcsInstance && this.fcsInstance.initializeTimeout) || 3, [this.initValidator]],
    });

    if (this.fcsInstance && this.fcsInstance.runtime == this.RuntimeCustomContainer) {
      this.getCirTagList();
    }

    if (this.fcsInstance.enableVpc) {
      this.isVirtualAccess = true;
      this.vpcId = this.fcsInstance.vpcInfo['vpcId'];
      this.subnetId = this.fcsInstance.vpcInfo['subnetId'];
    } else {
      this.isVirtualAccess = false;
    }
    if (this.fcsInstance) {
      this.envVariableData = this.fcsInstance['environment'] || [];
      this.envVariables = this.fcsInstance['environment'] || [];
    }
  }

  setControlVal(formControlName: string, val: string | boolean) {
    this.functionForm.get(formControlName).patchValue(val);
  }

  getCirTagList() {
    this.fcsService.getCirTagList().subscribe(res => {
      let data = JSON.parse(JSON.stringify(res));
      data = data.map(item => {
        let imageAndTag = item.path + ":" + item.name;
        let idx = imageAndTag.indexOf("/");
        imageAndTag = imageAndTag.slice(idx + 1);
        item.image = imageAndTag;
        return item;
      });
      this.cirImageList = data;
    }, err => {
    });
  }

  containerValidator(control: FormControl): any {
    if (!control.parent || control.parent.get("runtime").value != "custom-container") {
      return null
    }
    if (!control.value) {
      return {
        valid: false
      }
    }
    return null;
  }
  commandValidator(control: FormControl): any {
    if (!control.value) {
      return null
    }
    try {
      let data = JSON.parse(control.value)
      if (!(data instanceof Array)) {
        return {
          valid: false,
        }
      }
    } catch (error) {
      return {
        valid: false,
      }
    }
    return null;
  }
  initValidator(control: FormControl): any {
    if (!control.parent
      || control.parent.get("runtime").value == "custom-container"
      || control.parent.get("isInitialize").value == false) {
      return null
    }
    if (!control.value) {
      return {
        valid: false
      }
    }
    return null;
  }

  getVPCList() { //只初始化的时候，调用一次
    this.isLoadingVPC = true;
    this.fcsService.getVPCList(this.regionCode).subscribe(res => {
      this.isLoadingVPC = false;
      this.vpcList = [];
      this.subnetList = [];
      if (res && res.vpcs) {
        this.vpcList = res.vpcs || [];
        //如果改函数本来的关闭的，则给私有网络设置默认值
        if (!this.isVirtualAccess) {
          this.vpcId = this.vpcList.length > 0 ? this.vpcList[0].vpc_id : undefined;
        }
        if (this.vpcList.filter(item => item.vpc_id === this.vpcId).length > 0) {
          this.subnetList = this.vpcList.filter(item => item.vpc_id === this.vpcId)[0]['subnets'];
          //如果改函数本来的关闭的，则给私有网络设置默认值
          if (!this.isVirtualAccess) {
            this.subnetId = this.subnetList.length > 0 ? this.subnetList[0].subnet_id : undefined;
          }
        }
      }
    }, err => {
      this.isLoadingVPC = false;
    })
  }

  /**
   * 根据name返回表单控件实例
   * @param {*} name
   * @returns
   * @memberof GroupCreateComponent
   */
  getValidateForm(name: string | (string | number)[]) {
    return this.functionForm.get(name);
  }

  /**
   * 名称校验
   * @param {FormControl} control 控件实例
   */
  nameValidator(control: FormControl): any {
    let name: string = control.value;
    let pattern = new RegExp('^[a-z]([\\-_a-z0-9]{0,18})[a-z0-9]$');
    if (!pattern.test(name)) {
      return { functionName: true };
    }
    return null;
  }

  descriptionValid(control: FormControl): any {
    let des: string = control.value || '';
    // 最大支持500个英文字母、数字、空格、逗号、句号、中文
    let pattern = new RegExp('^[a-zA-Z0-9 ,，。.\u4e00-\u9fa5]{0,500}$');
    if (!des) return null;
    if (!pattern.test(des)) {
      return { description: true };
    }
    return null;
  }

  formatterMemorySize = value => Math.floor(value / 128) * 128;

  getInvalidMessage(name) {
    return this.functionFormComponent.getInvalidMessage(name);
  }

  virtualAccessChange(event) {
    if (!this.isVirtualAccess) {
      this.firstInit = true;
    }
  }

  vpcChange(event) {
    if (!this.firstInit) {
      this.subnetList = [];
      this.subnetId = undefined;
      let vpcs = this.vpcList.filter(item => item.vpc_id === this.vpcId);
      if (vpcs.length > 0) {
        this.subnetList = vpcs[0]['subnets'];
        if (this.subnetList.length > 0) {
          this.subnetId = this.subnetList[0].subnet_id;
        }
      }
    }
    this.firstInit = false;
    if (!this.vpcId) {
      this.vpcError = true;
    } else {
      this.vpcError = false;
    }
  }

  subnetChange(event) {
    if (!this.subnetId) {
      this.subnetError = true;
    } else {
      this.subnetError = false;
    }
  }

  createVPC() {
    let vpcUrl = Environment.application.productUrl + '/vpc/#/vpc?region=' + this.regionCode;
    window.open(vpcUrl, '_blank');
  }

  getEnvVariables(event) {
    this.envVariables = event['envVariableList'] || [];
    this.envValid = event['valid'];
  }

  /**
   * 提交表单
   *
   * @returns {boolean}
   * @memberof GroupCreateComponent
   */
  submitForm(): Promise<boolean> {
    //环境变量校验
    this.envVariableData = this.envVariables;
    if (!this.envValid) {
      this.needValid = true;
    }
    let skip1 = '', skip2 = '';
    if (this.isVirtualAccess) {
      skip1 = '';
      skip2 = '';
    } else {
      skip1 = 'vpc';
      skip2 = 'subnet';
    }
    let group = this.functionForm as FormGroup;
    for (const i in group.controls) {
      if (i == skip1 || i == skip2) {
        group.controls[i].clearValidators();
        group.controls[i].updateValueAndValidity();
      } else {
        group.controls[i].markAsDirty();
        group.controls[i].updateValueAndValidity();
      }
    }
    //返回一个promise对象才可以调用then等函数
    return new Promise((resolve, reject) => {
      this.envVariableData = this.envVariables;
      if (!group.valid || !this.envValid) {
        resolve(false);
      } else {
        let param: { [index: string]: any } = {};
        // 设置参数
        let description = this.functionForm.get('description').value;
        if (description != '') {
          param['description'] = description;
        }

        param['functionName'] = this.functionForm.get('functionName').value;
        param['memorySize'] = this.functionForm.get('memorySize').value;
        param['runtime'] = this.functionForm.get('runtime').value;
        param['handler'] = this.functionForm.get('handler').value;
        param['timeout'] = this.functionForm.get('timeout').value;
        param['concurrency'] = this.functionForm.get('concurrency').value;
        param['reserveNumber'] = this.functionForm.get('reserveNumber').value;
        let access = this.functionForm.get('internetAccess').value;
        param['enablePublic'] = access === false ? 0 : 1;
        if (this.isVirtualAccess) {
          param['enableVpc'] = 1;
          param['vpcInfo'] = {
            vpcId: this.vpcId,
            subnetId: this.subnetId
          }
        } else {
          param['enableVpc'] = 0;
        }
        param['environment'] = this.envVariables;

        // custom-contaienr
        if (param['runtime'] == this.RuntimeCustomContainer) {
          param['containerImage'] = this.functionForm.get('containerImage').value;
          param['containerCommand'] = this.functionForm.get('containerCommand').value;
          param['containerArgs'] = this.functionForm.get('containerArgs').value;
          param['containerPort'] = this.functionForm.get('containerPort').value;
        }
        // initialize function
        if (this.functionForm.get('isInitialize').value) {
          param['initializeHandler'] = this.functionForm.get('initializeHandler').value;
          param['initializeTimeout'] = this.functionForm.get('initializeTimeout').value;
        } else {
          param['initializeHandler'] = "";
          param['initializeTimeout'] = 0;
        }

        this.fcsService.updateFunction(this.fcsInstance.groupId, this.fcsInstance.functionId, param).subscribe(
          data => {
            if (data && data.functionName) {
              resolve(true);
              this.msgService.success(data['message'] || '函数配置成功！');
            } else {
              resolve(false);
              this.msgService.error(data['message']);
            }
          },
          err => {
            resolve(false);
          });
      }
    });
  }
  cancel() {

  }
}
